
(in-package #:smugmug)

(defmethod get-images ((album album) &optional password site-password)
  (let ((parameters `(("AlbumID" . ,(album-id album))
                      ("Heavy" . "true"))))
    (when password (push `("Password" . ,password) parameters))
    (when site-password (push `("SitePassword" . ,site-password) parameters))
    (let ((response (rest-request :session (session album)
                                  :method "smugmug.images.get"
                                  :parameters parameters)))
      (let ((images '()))
        (dom:map-node-list #'(lambda (image-node)
                               (push (make-instance 'image
                                                    :image-id (dom:get-attribute image-node "id")
                                                    :session (session album))
                                     images))
                           (dom:get-elements-by-tag-name response "Image"))
        (reverse images)))))

;;; TODO implement smugmug.images.getURLs

(defmethod get-image-info ((image image) &optional password site-password)
  (let ((parameters `(("ImageID" . ,(image-id image)))))
    (when password (push `("Password" . ,password) parameters))
    (when site-password (push `("SitePassword" . ,site-password) parameters))
    (let ((response (rest-request :session (session image)
                                  :method "smugmug.images.getInfo"
                                  :parameters parameters)))
      (let ((image-node (elt (dom:get-elements-by-tag-name response "Image") 0)))
        (flet ((parse-boolean (string)
                 (string/= "0" string))
               (parse-keywords (string)
                 (split-sequence:split-sequence #\Space string  :remove-empty-subseqs t))
               (parse-timestamp (string)
                 string))
          (let ((result '()))
            (dolist (attribute (list (list "FileName" :filename)
                                     (list "Caption" :caption)
                                     (list "Keywords" :keywords #'parse-keywords)
                                     (list "Position" :position #'parse-integer)
                                     (list "Date" :date #'parse-timestamp)
                                     (list "Format" :format)
                                     (list "Serial" :serial #'parse-boolean)
                                     (list "Watermark" :watermark #'parse-boolean)
                                     (list "Size" :size #'parse-integer)
                                     (list "Width" :width #'parse-integer)
                                     (list "Height" :height #'parse-integer)
                                     (list "MD5Sum" :md5sum)
                                     (list "LastUpdated" :last-updated #'parse-timestamp)
                                     (list "OriginalURL" :original-url #'puri:parse-uri)
                                     (list "LargeURL" :large-url #'puri:parse-uri)
                                     (list "MediumURL" :medium-url #'puri:parse-uri)
                                     (list "SmallURL" :small-url #'puri:parse-uri)
                                     (list "TinyURL" :tiny-url #'puri:parse-uri)
                                     (list "ThumbURL" :thumb-url #'puri:parse-uri)
                                     (list "AlbumURL" :album-url #'puri:parse-uri)))
              (destructuring-bind (attr keyword &optional (transform #'identity))
                  attribute
                (let ((value (dom:get-attribute image-node attr)))
                  (when value
                    (push (cons keyword (funcall transform value)) result)))))
            (reverse result)))))))

;;; TODO implement smugmug.images.getEXIF
;;; TODO implement smugmug.images.changeSettings
;;; TODO implement smugmug.images.changePosition
;;; TODO implement smugmug.images.delete
;;; TODO implement smugmug.images.getStats
